关于Spring Boot中使用Jetty容器开启HTTP2的配置

网上关于这次配置的参考资料很少,特此记录以备不时之需…

关于Spring Boot中使用Jetty容器开启HTTP2的配置

说明

  1. 使用的Spring Boot版本为:1.5.9.RELEASE;
  2. Jetty容器从9.0版本开始支持HTTP/2协议;

配置步骤

  1. 在pom文件中添加依赖:

    <dependency>
        <groupId>org.eclipse.jetty.http2</groupId>
        <artifactId>http2-server</artifactId>
    </dependency>
    
    <!-- 可选 -->
    <dependency>
        <groupId>org.eclipse.jetty.http2</groupId>
        <artifactId>http2-client</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-alpn-server</artifactId>
    </dependency>
    
    <!-- 可选 -->
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-alpn-client</artifactId>
    </dependency>
    
  2. 在配置类中添加如下配置代码:

    @Bean
    @Autowired
    public JettyEmbeddedServletContainerFactory embeddedServletContainerFactory(ServerProperties serverProperties) {
    
        JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
        JettyServerCustomizer customizer = new JettyServerCustomizer() {
    
            @Override
            public void customize(Server server) {
                if ((serverProperties.getSsl() != null) && serverProperties.getSsl().isEnabled()) {
                    ServerConnector connector = (ServerConnector) server.getConnectors()[0];
                    int port = connector.getPort();
                    SslContextFactory sslContextFactory = connector.getConnectionFactory(SslConnectionFactory.class).getSslContextFactory();
                    HttpConfiguration httpConfiguration = connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration();
                    configureSslContextFactory(sslContextFactory);
    
                    ConnectionFactory[] connectionFactories = createConnectionFactories(sslContextFactory, httpConfiguration);
                    ServerConnector serverConnector = new ServerConnector(server, connectionFactories);
                    serverConnector.setPort(port);
    
                    server.setConnectors(new Connector[] { serverConnector });
                }
            }
    
            private void configureSslContextFactory(SslContextFactory sslContextFactory) {
                sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
                //sslContextFactory.setUseCipherSuitesOrder(true);
            }
    
            private ConnectionFactory[] createConnectionFactories(SslContextFactory sslContextFactory, HttpConfiguration httpConfiguration) {
                SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(sslContextFactory, "alpn");
                ALPNServerConnectionFactory alpnServerConnectionFactory = new ALPNServerConnectionFactory("h2", "h2-17", "h2-16", "h2-15", "h2-14");
                HTTP2ServerConnectionFactory http2ServerConnectionFactory = new HTTP2ServerConnectionFactory(httpConfiguration);
                return new ConnectionFactory[] { sslConnectionFactory, alpnServerConnectionFactory, http2ServerConnectionFactory };
            }
        };
        factory.addServerCustomizers(customizer);
        return factory;
    }
    

如何判断网站是否使用HTTP/2

  1. chrome://net-internals/#http2,在浏览器输入chrome://net-internals/打开网络观察组件,然后选择HTTP/2;
  2. chrome.loadTimes,支持http2的chrome版本,可通过其提供的chrome.loadTimes API来进行判断,适用于所有的chrome内核;

    //参考代码:JS版本
    (function(){
        // 保证这个方法只在支持loadTimes的chrome浏览器内核下执行
        if(window.chrome && typeof chrome.loadTimes === 'function') {
            var loadTimes = window.chrome.loadTimes();
            var spdy = loadTimes.wasFetchedViaSpdy;
            var info = loadTimes.npnNegotiatedProtocol || loadTimes.connectionInfo;
            // 将h2作为判断标识
            if(spdy && /^h2/i.test(info)) {
                return console.info('本站点使用了HTTP/2');
            }
        }
        console.warn('本站点没有使用HTTP/2');
    })();
    

参考资料

  1. http://blog.csdn.net/chenmoquan/article/details/76906524
文章目录
,